package org.dousb.doupicturebackend.manager.websocket.disruptor;


import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import lombok.extern.slf4j.Slf4j;
import org.dousb.doupicturebackend.manager.websocket.model.PictureEditRequestMessage;
import org.dousb.doupicturebackend.model.entity.User;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;


/**
 * PictureEditEventProducer
 * 图片编辑事件生产者，用于将图片编辑事件发布到Disruptor中
 *
 * @author 豆沙包
 * @version 1.0
 * @since 2025-11-06  19:30
 */
@Component
@Slf4j
public class PictureEditEventProducer {

    @Resource
    private Disruptor<PictureEditEvent> pictureEditEventDisruptor;

    /**
     * 发布图片编辑事件的方法
     *
     * @param pictureEditRequestMessage 图片编辑请求消息
     * @param excludeSession            需要排除的WebSocket会话，通常用于不向发送者自己推送消息
     * @param user                      发起请求的用户信息
     * @param pictureId                 图片ID
     */
    public void publishEvent(PictureEditRequestMessage pictureEditRequestMessage, WebSocketSession excludeSession, User user, Long pictureId) {
        // 获取Disruptor的环形缓冲区
        RingBuffer<PictureEditEvent> ringBuffer = pictureEditEventDisruptor.getRingBuffer();
        // 获取下一个可用的序列号
        long next = ringBuffer.next();
        // 获取该序列号对应的事件对象
        PictureEditEvent pictureEditEvent = ringBuffer.get(next);
        // 设置事件的各种属性
        pictureEditEvent.setPictureEditRequestMessage(pictureEditRequestMessage);
        pictureEditEvent.setWebSocketSession(excludeSession);
        pictureEditEvent.setUser(user);
        pictureEditEvent.setPictureId(pictureId);
        // 发布事件，使消费者能够处理
        ringBuffer.publish(next);
    }

    /**
     * 销毁方法，在Bean被销毁前调用
     * 该注解@PreDestroy表示该方法会在容器销毁Bean之前执行
     * 通常用于资源释放、清理工作等
     */
    @PreDestroy
    public void destroy() {
        // 关闭Disruptor事件处理器，释放相关资源
        pictureEditEventDisruptor.shutdown();
    }
}